<?php

/**
 * Albireo Kernel
 *
 * @copyright  Copyright (c) 2010 Albireo Solutions
 * @package    Kernel
 */
namespace Albireo;

use \dibi;
use \Nette\Object;

/**
 * The helping class used for generating menus according to the ACL access rules.
 *
 * @author Pavel
 */

class MenuGenerator extends Object {

    /**
     * @deprecated universalMenu() should be used instead
     *
     * @param <type> $user
     * @param <type> $action
     * @param array $items
     * @return <type>
     */
    public static function generateMainMenu($user, $action, array $items) {
        $result = array();
        foreach($items as $presenter => $text) {
            try {
                if ($user->isAllowed($presenter, $action)) {
                    $result[$presenter] = $text;
                }
            } catch (\InvalidStateException $resource) {
                continue;
            }
        }
        return $result;
    }

    /**
     *
     * The universal menu generating function (it's not static because of the
     * possible security problems). The first parameter is the Nette user
     * currently logged in, so the menu is created for him (for his privileges).
     * The second parameter is the array of the menu items we want to process.
     *
     * It looks like this:
     *      array (
     *          "MyModule:MyPresenter" => array (
     *                                      "action" => "myAction",
     *                                      "some item" => "something",
     *                                      "another item" => "anything"
     *                                    ),
     *          "MyModule:AnotherPresenter" => array (
     *                                      "action" => "someOtherAction",
     *                                      ...
     *          ...
     *      );
     *
     * The indexes of the array, e.g "MyModule:MyPresenter", stand for
     * the presenter name or more precisely the module+presenter name. It's
     * fully qualified Module+Presenter name in the sense of Nette application.
     *
     * Then, every member of the main array $items (it's also the array, indexed
     * by the presenter name) should contain the field "action". This represents
     * the action name within the presenter (it's privilege in the albireo ACL
     * implementation). If the "action" member is not present, it's used string
     * 'default' as default.
     *
     * The member array (i.e the "most inside" one) can contain any other data
     * we want to give over the method. The data are passed to the result
     * unmodified. You can put there some titles, descriptions, icon paths or
     * anything else you need to generate your super cool menu.
     *
     * The result is array of the items the user can access. Every index is
     * now fully qualified path WITH THE ACTION within the presenter. The data
     * (every "small" array) is unmodified data from the given parameter $items.
     * 
     * It looks like this:
     *      array (
     *          "MyModule:MyPresenter:myAction" => array (
     *                                      "action" => "myAction",
     *                                      "some item" => "something",
     *                                      "another item" => "anything"
     *                                    ),
     *          "MyModule:AnotherPresenter:someOtherAction" => array (
     *                                      "action" => "someOtherAction",
     *                                      ...
     *          ...
     *      );
     *
     * Of course, the result does not contain the presenters/actions the user
     * can't access.
     *
     * When invalid resource name (presenter name) is given, it is skipped and
     * not present in the result. But the method goes on and completes the job.
     * 
     * @param <type> $user
     * @param array $items the list of items we want to proceed to the menu
     *      REQUIRED index presenter - fully qualified path of the presenter
     *      OPTIONAL field action - the action in the presenter
     *      OPTIONAL any other data we wish
     * @return array the menu, where the index is like Presenter:action, the
     *      field contains the original variable $items
     */
    public function universalMenu($user, array $items) {
        $result = array();
        foreach($items as $presenter => $otherItems) {
            $action = isset($otherItems["action"]) ? $otherItems["action"] : "default";
            try {
                if ($user->isAllowed($presenter, $action)) {
                    $result[$presenter . ":". $action] = $otherItems;
                }
            } catch (\InvalidStateException $resource) {
                continue;
            }
        }
        return $result;
    }
}